#include "Caja.h"

#include <sstream>

#include <ConfigurationFile.h>
#include <Logger.h>

Caja::Caja()
{
	std::string keyCaja = ConfigurationFile::getProperty(Properties::KEY_CAJA);
	
	// Creo/obtengo la cola donde estan las solicitudes de caja
	m_ColaPedidosDeCaja.crear(keyCaja, CreationMode::CREAR_SI_NO_EXISTE);
	
	// Inicio el saldo
	m_Saldo = 0;
}

Caja::~Caja()
{
	m_ColaPedidosDeCaja.eliminar();
}

bool Caja::hayPedidosDeCaja()
{
	if(m_ColaPedidosDeCaja.leer(-TipoPedidoCaja::getLowestPriorityValue(), &m_UltimoPedido) < 0)
		throw BaseException("Ocurrio un error al leer de la cola de pedidos de la caja");
	
	bool hayPedidos = false;
	if(m_UltimoPedido.mtype == TipoPedidoCaja::TIPO_CONSULTA 
		|| m_UltimoPedido.mtype == TipoPedidoCaja::TIPO_GUARDADO)
	{
		hayPedidos = true;
	}
	
	return hayPedidos;
}

void Caja::procesarPedidoDeCaja()
{
	try
	{
		TipoPedidoCaja tipo(m_UltimoPedido.mtype);
		std::stringstream detalleOperacion;
		detalleOperacion << "CAJA >> Se proceso pedido de tipo " << tipo.toString();
		m_UltimoPedido.returnCode = ReturnCode::OK;
		
		if(m_UltimoPedido.mtype == TipoPedidoCaja::TIPO_CONSULTA)
		{
			// Cargo el saldo en el mensaje de respuesta
			m_UltimoPedido.value = m_Saldo;
			detalleOperacion << ". La recaudacion de la caja es de " << m_Saldo;
		}
		else if(m_UltimoPedido.mtype == TipoPedidoCaja::TIPO_GUARDADO)
		{
			// Guardo el monto solicitado
			m_Saldo += m_UltimoPedido.value;
			detalleOperacion << ". Se guardo en la caja " << m_UltimoPedido.value;
		}
		else
		{
			m_UltimoPedido.returnCode = ReturnCode::ERROR;
			Logger::getInstance()->error("La operacion recibida es invalida");
		}
		
		// Cambio el mtype por el del receptor
		m_UltimoPedido.mtype = m_UltimoPedido.sourceId;
		
		// Envio la respuesta
		m_ColaPedidosDeCaja.escribir(m_UltimoPedido);
		
		if(m_UltimoPedido.returnCode == ReturnCode::OK)
			Logger::getInstance()->info(detalleOperacion.str());
	}
	catch(const BaseException& e)
	{
		std::stringstream eMsg;
		eMsg << "Ocurrio un error al realizar la siguiente operacion: " << TipoPedidoCaja(m_UltimoPedido.mtype).toString();
		eMsg << ". " << e.what();
		Logger::getInstance()->error(eMsg.str());
	}
}